﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace LinqToSQL.stuff
{
    static public class Other
    {

        static public class RegEx
        {
            static public void MatchTest()
            {
                string string1 = "This is a test string";
                // find any nonwhitespace followed by whitespace
                Regex theReg = new Regex(@"(\S+)\s");
                // get the collection of matches
                MatchCollection theMatches = theReg.Matches(string1);
                // iterate through the collection
                foreach (Match theMatch in theMatches)
                {
                    Console.WriteLine("theMatch.Length: {0}",
                    theMatch.Length);
                    if (theMatch.Length != 0)
                    {
                        Console.WriteLine("theMatch: {0}",
                        theMatch.ToString());
                    }
                }
            }

            static public void SplitTest()
            {
                string s1 = "One,Two,Three Liberty Associates, Inc.";
                Regex theRegex = new Regex(" |, |,");
                StringBuilder sBuilder = new StringBuilder();
                int id = 1;
                foreach (string subString in theRegex.Split(s1))
                    sBuilder.AppendFormat("{0}: {1}\n", id++, subString);
                Console.WriteLine("{0}", sBuilder);
            }

            static public void GroupTest()
            {
                string string1 = "04:03:27 127.0.0.0 LibertyAssociates.com";
                // group time = one or more digits or colons followed by space
                Regex theReg = new Regex(@"(?<time>(\d|\:)+)\s" +
                    // ip address = one or more digits or dots followed by space
                    // ?<ip> names the ip group
                @"(?<ip>(\d|\.)+)\s" +
                    // site = one or more characters
                @"(?<site>\S+)");
                // get the collection of matches
                MatchCollection theMatches = theReg.Matches(string1);
                // iterate through the collection
                foreach (Match theMatch in theMatches)
                {
                    if (theMatch.Length != 0)
                    {
                        Console.WriteLine("\ntheMatch: {0}",
                        theMatch.ToString());
                        Console.WriteLine("time: {0}",
                        theMatch.Groups["time"]);
                        Console.WriteLine("ip: {0}",
                        theMatch.Groups["ip"]);
                        Console.WriteLine("site: {0}",
                        theMatch.Groups["site"]);
                    }
                }
            }

            static public void GroupTest2()
            {
                // the string to parse
                // note that names appear in both
                // searchable positions
                string string1 = "04:03:27 Jesse 0.0.0.127 Liberty ";
                // regular expression that groups company twice
                Regex theReg = new Regex(@"(?<time>(\d|\:)+)\s" +
                @"(?<company>\S+)\s" +
                @"(?<ip>(\d|\.)+)\s" +
                @"(?<company>\S+)\s");
                // get the collection of matches
                MatchCollection theMatches =
                theReg.Matches(string1);
                // iterate through the collection
                foreach (Match theMatch in theMatches)
                {
                    if (theMatch.Length != 0)
                    {
                        Console.WriteLine("theMatch: {0}",
                        theMatch.ToString());
                        Console.WriteLine("time: {0}",
                        theMatch.Groups["time"]);
                        Console.WriteLine("ip: {0}",
                        theMatch.Groups["ip"]);
                        Console.WriteLine("Company: {0}",
                        theMatch.Groups["company"]);
                        // iterate over the captures collection
                        // in the company group within the
                        // groups collection in the match
                        foreach (Capture cap in theMatch.Groups["company"].Captures)
                        {
                            Console.WriteLine("cap: {0}", cap.ToString());
                        }
                    }
                }

            }
        }

        public class AsyncExecution
        {
            //private class ClassWithDelegate
            //{
            //    // a multicast delegate that encapsulates a method
            //    // that returns an int
            //    public delegate int DelegateThatReturnsInt();
            //    public DelegateThatReturnsInt theDelegate;
            //    public void Run()
            //    {
            //        for (; ; )
            //        {
            //            // sleep for a half second
            //            Thread.Sleep(500);
            //            if (theDelegate != null)
            //                // explicitly invoke each delegated method
            //                foreach (DelegateThatReturnsInt del in theDelegate.GetInvocationList())
            //                    // invoke asynchronously
            //                    // pass the delegate in as a state object
            //                    del.BeginInvoke(new AsyncCallback(ResultsReturned), del);
            //        }
            //    }

            //    // callback method to capture results
            //    private void ResultsReturned(IAsyncResult iar)
            //    {
            //        // cast the state object back to the delegate type
            //        DelegateThatReturnsInt del = (DelegateThatReturnsInt)iar.AsyncState;
            //        // call EndInvoke on the delegate to get the results
            //        int result = del.EndInvoke(iar);
            //        Console.WriteLine("Delegate returned result: {0}", result);
            //    }
            //}
            //private class FirstSubscriber
            //{
            //    private int myCounter = 0;
            //    public void Subscribe(ClassWithDelegate theClassWithDelegate)
            //    {
            //        theClassWithDelegate.theDelegate += new ClassWithDelegate.DelegateThatReturnsInt(DisplayCounter);
            //    }
            //    public int DisplayCounter()
            //    {
            //        Console.WriteLine("Busy in DisplayCounter...");
            //        Thread.Sleep(10000);
            //        Console.WriteLine("Done with work in DisplayCounter...");
            //        return ++myCounter;
            //    }
            //}
            //private class SecondSubscriber
            //{
            //    private int myCounter = 0;
            //    public void Subscribe(ClassWithDelegate theClassWithDelegate)
            //    {
            //        theClassWithDelegate.theDelegate += new ClassWithDelegate.DelegateThatReturnsInt(Doubler);
            //    }
            //    public int Doubler()
            //    {
            //        return myCounter += 2;
            //    }
            //}

            //public static void Run()
            //{
            //    ClassWithDelegate theClassWithDelegate =
            //    new ClassWithDelegate();
            //    FirstSubscriber fs = new FirstSubscriber();
            //    fs.Subscribe(theClassWithDelegate);
            //    SecondSubscriber ss = new SecondSubscriber();
            //    ss.Subscribe(theClassWithDelegate);
            //    theClassWithDelegate.Run();
            //} 

            public enum ResultStatus { undefined, ok, error };

            static private StreamWriter log;

            private class AsyncPowerResult
            {
                public ResultStatus status { get; set; }
                public int arg { get; set; }
                public int value { get; set; }
            }

            static public void Test()
            {
                log = new StreamWriter("result.txt");
                //start several threads to calculate powers
                log.WriteLine(string.Format("Starting threads"));
                Func<int, AsyncPowerResult> asyncPowerOf = new Func<int, AsyncPowerResult>(PowerOf);
                for (int i = 0; i < 100; i++)
                {
                    if (i % 5 == 0)
                        asyncPowerOf.BeginInvoke(i, new AsyncCallback(PowerOfResultAnalyzer), asyncPowerOf);
                    else
                        log.WriteLine(string.Format("Skipping {0}", i));
                }
                //wait them for finish
                log.WriteLine(string.Format("Waiting threads to finish"));
                Thread.Sleep(10000);
                log.WriteLine(string.Format("Closing"));
                log.Close();
            }

            private static AsyncPowerResult PowerOf(int x)
            {

                log.WriteLine(string.Format("Calculating power of {0}", x));
                Thread.Sleep(500);
                if (x % 10 == 0)
                {
                    log.WriteLine(string.Format("PowerOf Error: can't calculate power of {0} (is divibile by 10)", x));
                    return new AsyncPowerResult() { status = ResultStatus.error, arg = x, value = -1 };
                }
                log.WriteLine(string.Format("PowerOf Result: power of {0} is {1} ", x, x * x));
                return new AsyncPowerResult() { status = ResultStatus.ok, arg = x, value = x * x };
            }

            private static void PowerOfResultAnalyzer(IAsyncResult execResult)
            {
                Func<int, AsyncPowerResult> caller = (Func<int, AsyncPowerResult>)execResult.AsyncState;
                AsyncPowerResult result = caller.EndInvoke(execResult);
                log.WriteLine(string.Format("Execution Result is {0} for {1}", result.status, result.arg));
            }
        }
    }
}
